package com.hksj.ecm.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.ecm.entity.EnergyRate;
import com.hksj.ecm.entity.EnergyType;
import com.hksj.ecm.mapper.EnergyTypeMapper;
import com.hksj.ecm.vo.EnergyRateVO;
import com.hksj.ecm.vo.EnergyTypeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zengke
 * @version 1.0
 * @see EnergyTypeService
 * @since 2024/8/6 17:19
 */

@Service
public class EnergyTypeService extends ServiceImpl<EnergyTypeMapper, EnergyType> {

    @Autowired
    private EnergyRateService energyRateService;

    /**
     * 同步能源类型
     * @return
     */
    public String syncEnergyType(){

        //查询产品类型中的能耗类型数据
        List<EnergyType> energyTypeListFromProductCategory = baseMapper.queryEnergyTypeFromProductCategory();

        //对查询出的能耗类型数据进行整理,将水表和电表的能源类型名称改为水、电
        List<EnergyType> energyTypeList = energyTypeListFromProductCategory.stream().peek(energyType -> {
            //若energyType的code为DianB则name修改成电
            if ("DianB".equals(energyType.getCode())) {
                energyType.setName("电");
            }

            //若energyType的code为ShuiB则name修改成水
            if ("ShuiB".equals(energyType.getCode())) {
                energyType.setName("水");
            }
        }).collect(Collectors.toList());

        //查询数据库中已有的能耗类型数据
        List<EnergyType> energyTypeListFromDB = baseMapper.selectList(null);

        //使用CollectionUtil.subtract做差集、CollectionUtil.emptyIfNull进行非空处理
        //energyTypeList 与energyTypeListFromDB的差集 为需要新增的元素
        Collection<String> toAddList = CollectionUtil.subtract(CollectionUtil.emptyIfNull(energyTypeList).stream().map(EnergyType::getCode).collect(Collectors.toList()), CollectionUtil.emptyIfNull(energyTypeListFromDB).stream().map(EnergyType::getCode).collect(Collectors.toList()));

        //将要新增的能耗类型
        List<EnergyType> toAddEnergyTypeList = new ArrayList<>();
        if (!CollectionUtil.isEmpty(toAddList)){
            List<EnergyType> collect = energyTypeList.stream().filter(eachItem -> toAddList.contains(eachItem.getCode())).collect(Collectors.toList());
            toAddEnergyTypeList.addAll(collect);
        }

        //energyTypeListFromDB 与 energyTypeList 的差集为需要删除的元素
        Collection<String> toDeleteList = CollectionUtil.subtract(CollectionUtil.emptyIfNull(energyTypeListFromDB).stream().map(EnergyType::getCode).collect(Collectors.toList()), CollectionUtil.emptyIfNull(energyTypeList).stream().map(EnergyType::getCode).collect(Collectors.toList()));

        //将要删除的能耗类型
        List<EnergyType> toDeleteEnergyTypeList = new ArrayList<>();
        if (!CollectionUtil.isEmpty(toDeleteList)){
            List<EnergyType> collect = energyTypeListFromDB.stream().filter(eachItem -> toDeleteList.contains(eachItem.getCode())).collect(Collectors.toList());
            toDeleteEnergyTypeList.addAll(collect);
        }

        //先删除已有能耗类型数据
        super.removeByIds(toDeleteEnergyTypeList.stream().map(EnergyType::getId).collect(Collectors.toList()));

        // 再添加以上能耗类型数据
        super.saveBatch(toAddEnergyTypeList);

        return "同步能耗类型数据成功";
    }

    /**
     * 查询能耗类型树
     * @return
     */
    public List<EnergyType> queryEnergyTypeTree(){

        //查询所有能耗类型列表
        List<EnergyType> allEnergyTypeList = baseMapper.selectList(null);

        //能耗的父节点为 "-190-" 返回能耗类型树
        return getChildren("-190-", allEnergyTypeList);
    }

    /**
     * 查询孩子节点
     * @param parentId 父节点id
     * @param allEnergyTypeList 所有节点
     * @return 孩子节点集合
     */
    public List<EnergyType> getChildren(String parentId,List<EnergyType> allEnergyTypeList){

        //查询指定的节点集合中的子节点列表
        List<EnergyType> children = allEnergyTypeList.stream().filter(c -> Objects.equals(c.getParentId(), parentId)).collect(Collectors.toList());

        //判断子节点列表是否为空
        if (ObjectUtils.isEmpty(children)){
            //若为空则直接返回空的集合
            return new ArrayList<>();
        }

        //否则遍历子节点列表
        children.forEach(child -> {

            //获取子节点的id
            String pId = child.getId();

            //递归查询子节点对应的 子节点列表
            List<EnergyType> cChildren = getChildren(pId, allEnergyTypeList);

            //将子节点列表添加到 子节点中
            child.getChildren().addAll(cChildren);
        });

        //返回子节点列表
        return children;
    }

    //维护能耗类型
    public String maintenanceEnergyType(EnergyType energyType){

        //根据code做更新能耗类型的操作
        lambdaUpdate().eq(EnergyType::getCode,energyType.getCode())
                .update(energyType);

        return "保存成功";
    }

    /**
     * 通过能耗类型code查询能耗类型明细
     * @param energyTypeCode
     * @return
     */
    public EnergyTypeVO queryEnergyRateByEnergyTypeCode(String energyTypeCode){

        //通过code查询能耗类型
        EnergyType energyType = lambdaQuery().eq(EnergyType::getCode, energyTypeCode).one();

        //将energyType转为energyTypeVO
        EnergyTypeVO energyTypeVO = Convert.convert(EnergyTypeVO.class, energyType);

        //通过energyTypeCode查询费率
        List<EnergyRateVO> energyRateVOList = energyRateService.lambdaQuery()
                .eq(EnergyRate::getEnergyTypeCode, energyTypeCode)
                .list()
                .stream()
                .map(energyRate -> Convert.convert(EnergyRateVO.class,energyRate))
                .collect(Collectors.toList());

        //将费率列表设置到能耗类型VO中
        energyTypeVO.setEnergyRateList(energyRateVOList);

        //返回能耗类型明细
        return energyTypeVO;
    }

    public EnergyTypeVO queryEnergyTypeDetail(String energyTypeCode) {
        //能耗类型信息
        EnergyType energyType = lambdaQuery().eq(EnergyType::getCode, energyTypeCode).one();

        //若查询的能耗信息为空直接返回null
        if (ObjectUtils.isEmpty(energyType)){
            return null;
        }

        //不为空,将能耗信息转为能耗类型明细
        EnergyTypeVO energyTypeVO = Convert.convert(EnergyTypeVO.class, energyType);

        //查询能耗费率列表
        List<EnergyRate> energyRateList = energyRateService.lambdaQuery().eq(EnergyRate::getEnergyTypeCode, energyTypeCode).list();

        if (!ObjectUtils.isEmpty(energyRateList)){

            //能耗费率列表不为空,将能耗费率列表类型 转为 能耗费率明细列表 将能耗费率列表按照起始值的大小进行顺序排序
            List<EnergyRateVO> energyRateVOList = energyRateList.stream().sorted((Comparator.comparing(o -> new BigDecimal(o.getStartRangeValue())))).map(energyRate -> Convert.convert(EnergyRateVO.class, energyRate)).sorted(Comparator.comparing(energyRateVO -> new BigDecimal(energyRateVO.getStartRangeValue()))).collect(Collectors.toList());

            //将能耗费率结果设置到energyTypeVO
            energyTypeVO.setEnergyRateList(energyRateVOList);
        }

        //返回能耗类型明细
        return energyTypeVO;
    }
}
